package com.eimf.saf.security.util.secret;

import java.security.MessageDigest;
import java.security.Security;
import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import sun.misc.BASE64Encoder;

import com.sun.crypto.provider.SunJCE;

/**
 * @author eden
 * @date 2013-11-25 下午3:45:34
 * @Description: TODO(这里用一句话描述这个类的作用)
 */
public class CryptUtil
{

    private static Log logger = LogFactory.getLog(CryptUtil.class);

    private static MessageDigest md = null;

    public static final String ALGORITHM_PBEWithMD5AndDES = "PBEWithMD5AndDES";

    public static final String ALGORITHM_DES = "DES";

    private static final byte[] sale =
    { 65, 82, 103, 54, 48, 83, 99, 71 };

    static
    {
        try
        {
            CryptUtil.md = MessageDigest.getInstance("MD5");
        } catch (final Exception ex)
        {
            throw new RuntimeException(ex);
        }
    }

    public static final byte[] encrypt(final String str, final String key, final String algorithm) throws Exception
    {
        final PBEKeySpec pbks = new PBEKeySpec(key.toCharArray());
        final SecretKeyFactory kf = SecretKeyFactory.getInstance(algorithm);
        final SecretKey k = kf.generateSecret(pbks);
        final Cipher cp = Cipher.getInstance(algorithm);
        final PBEParameterSpec ps = new PBEParameterSpec(CryptUtil.sale, 1000);
        cp.init(1, k, ps);
        final byte[] ptext = str.getBytes("UTF-8");
        final byte[] ctext = cp.doFinal(ptext);
        return ctext;
    }

    public static final byte[] desCrypt(final String s, final String key) throws Exception
    {
        Security.addProvider(new SunJCE());
        final KeySpec keySpec = new DESKeySpec(key.getBytes());
        final SecretKey secretKey = SecretKeyFactory.getInstance("DES", "SunJCE").generateSecret(keySpec);
        final Cipher ecipher = Cipher.getInstance(secretKey.getAlgorithm());
        ecipher.init(1, secretKey);
        return ecipher.doFinal(s.getBytes());
    }

    public static final byte[] desCrypt(final byte[] b, final String key) throws Exception
    {
        Security.addProvider(new SunJCE());
        final KeySpec keySpec = new DESKeySpec(key.getBytes());
        final SecretKey secretKey = SecretKeyFactory.getInstance("DES", "SunJCE").generateSecret(keySpec);
        final Cipher ecipher = Cipher.getInstance(secretKey.getAlgorithm());
        ecipher.init(1, secretKey);
        return ecipher.doFinal(b);
    }

    public static final String desCryptWithBase64(final String s, final String key) throws Exception
    {
        return CryptUtil.base64Encode(CryptUtil.desCrypt(s, key));
    }

    public static final String desDecrypt(final byte[] s, final String key) throws Exception
    {
        Security.addProvider(new SunJCE());
        final KeySpec keySpec = new DESKeySpec(key.getBytes());
        final SecretKey secretKey = SecretKeyFactory.getInstance("DES", "SunJCE").generateSecret(keySpec);
        final Cipher ecipher = Cipher.getInstance(secretKey.getAlgorithm());
        ecipher.init(2, secretKey);
        return new String(ecipher.doFinal(s));
    }

    public static final String md5(final byte[] b)
    {
        return CryptUtil.base64Encode(CryptUtil.md.digest(b));
    }

    public static final String md5(final String s)
    {
        return CryptUtil.base64Encode(CryptUtil.md.digest(s.getBytes()));
    }

    public static final byte[] md5byte(final byte[] b)
    {
        return CryptUtil.md.digest(b);
    }

    public static final String base64Encode(final byte[] b)
    {
        final BASE64Encoder encoder = new BASE64Encoder();
        String s = encoder.encode(b);
        s = s.replace('\r', ' ').replace('\n', ' ').replaceAll(" ", "");
        return s;
    }
}
